package com.telit.firecommand.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaolyuh.annotation.CacheEvict;
import com.github.xiaolyuh.annotation.Cacheable;
import com.telit.common.entity.PageData;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.PinyinAPI;
import com.telit.dispose.entity.resourceManagement.Dict;
import com.telit.dispose.feign.RemoteDisposeService;
import com.telit.firecommand.dao.CommEmergencyPlanDao;
import com.telit.firecommand.entity.CommEmergencyPlan;
import com.telit.firecommand.entity.PlanType;
import com.telit.firecommand.service.EmergencyPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @Author:zhangwei
 * @Description:
 * @Time:Created on 2021/8/3 9:56
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class EmergencyPlanServiceImpl extends ServiceImpl<CommEmergencyPlanDao, CommEmergencyPlan> implements
        EmergencyPlanService {

    @Autowired
    private RemoteDisposeService remoteDisposeService;

    /**
     * 新增预案信息
     *
     * @param emergencyPlan
     */
    @Override
    @CacheEvict(value = {"firecommand:emergencyPlan:list", "firecommand:emergencyPlan:selectByPage"}, allEntries = true)
    public void add(CommEmergencyPlan emergencyPlan) {
        emergencyPlan.setCreateTime(new Date());
        emergencyPlan.setUpdateTime(new Date());
        emergencyPlan.setDeleted("0");
        if (baseMapper.insert(emergencyPlan) <= 0) {
            throw new ForestBaseException("添加应急预案失败");
        }
    }

    @Override
    public CommEmergencyPlan info(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 分页条件查询应急预案信息
     *
     * @param current
     * @param size
     * @param startTime
     * @param endTime
     * @param planName
     *
     * @return
     */
    @Override
    @Cacheable(value = "firecommand:emergencyPlan:selectByPage", depict = "分页条件查询应急预案信息")
    public IPage<CommEmergencyPlan> selectByPage(Integer current, Integer size, String startTime, String endTime,
                                                 String planName, String planType, String fileCode) {
        IPage<CommEmergencyPlan> emergencyPlanIPage = new Page<>(current, size);
        return baseMapper.selectPageByCondition(emergencyPlanIPage, startTime, endTime, planName, planType, fileCode);
    }

    /**
     * 无分页条件查询应急预案信息
     *
     * @param startTime
     * @param endTime
     * @param planName
     *
     * @return
     */
    @Override
    public List<CommEmergencyPlan> selectByNoPage(String startTime, String endTime, String planName, String planType,
                                                  String fileCode) {
        return baseMapper.selectByConditionNoPage(startTime, endTime, planName, planType, fileCode);
    }

    /**
     * 更新应急预案信息
     *
     * @param emergencyPlan
     */
    @Override
    @CacheEvict(value = {"firecommand:emergencyPlan:list", "firecommand:emergencyPlan:selectByPage"}, allEntries = true)
    public void updateData(CommEmergencyPlan emergencyPlan) {
        emergencyPlan.setUpdateTime(new Date());
        if (baseMapper.updateById(emergencyPlan) <= 0) {
            throw new ForestBaseException("修改应急预案失败");
        }
    }

    /**
     * 逻辑删除应急预案信息
     *
     * @param id
     */
    @Override
    @CacheEvict(value = {"firecommand:emergencyPlan:list", "firecommand:emergencyPlan:selectByPage"}, allEntries = true)
    public void deleteById(Long id) {
        UpdateWrapper<CommEmergencyPlan> commEmergencyPlanUpdateWrapper = new UpdateWrapper<>();
        commEmergencyPlanUpdateWrapper.eq("id", id).set("deleted", "1");
        baseMapper.update(null, commEmergencyPlanUpdateWrapper);
       /* if(baseMapper.deleteById(id) <= 0){
            throw new ForestBaseException("删除应急预案失败");
        }*/
    }

    /**
     * 根据ID数组删除应急预案信息表
     *
     * @param ids
     *
     * @return
     */
    @Override
    @CacheEvict(value = {"firecommand:emergencyPlan:list", "firecommand:emergencyPlan:selectByPage"}, allEntries = true)
    public List<Integer> deleteBatch(Long[] ids) {
        List<Integer> values = new ArrayList<Integer>();
        if (ids != null && ids.length > 0) {
            for (Long id : ids) {
                values.add(baseMapper.deleteById(id));
            }
        }
        return values;
    }

    @Override
    public void addPlanType(PlanType planType) {
        Dict dict = new Dict();
        //根据转成汉字
        dict.setConfigCode(PinyinAPI.getPinYinHeadChar(planType.getConfigName()));
        dict.setConfigName(planType.getConfigName());
        dict.setSort(planType.getSort());
        dict.setParentId(9L);
        remoteDisposeService.dictInsert(dict);
    }

    @Override
    public void deletePlanType(String id) {
        //判断该应急预案是否在使用
        Integer count = baseMapper.selectUsePlanType(id);
        if (count != null && count > 0) {
            throw new ForestBaseException("该应急预案正在使用中");
        }
        remoteDisposeService.deleteDictById(Long.parseLong(id));
    }

    @Override
    @Cacheable(value = "firecommand:emergencyPlan:list", depict = "无分页条件查询应急预案信息")
    public List<CommEmergencyPlan> list(String startTime, String endTime, String planName, String planType,
                                        String fileCode) {
        List<CommEmergencyPlan> emergencyPlanList = baseMapper.selectByConditionNoPage(startTime, endTime, planName,
                planType, fileCode);
//        List<CommEmergencyPlan> resultList = new ArrayList<CommEmergencyPlan>();
//        if (emergencyPlanList != null && emergencyPlanList.size() > 0) {
//            emergencyPlanList.forEach(object -> {
//                if (StringUtils.isNotEmpty(object.getImageUrl())) {
//
//                    List<Map<String, Object>> oldFileList = JSONArray.parseObject(object.getImageUrl(), List.class);
//                    Map<String, Object> previewUrlMap = new HashMap<>();
//                    for (Map<String, Object> map : oldFileList) {
//                        for (String key : map.keySet()) {
//                            //TODO:v1.1.0
////                            String filepath = (String) map.get(key);
////                            previewUrlMap.put(key, MinioUtils.previewImg(filepath));
//                        }
//                    }
//
//                    object.setPreviewUrl(JSONObject.toJSONString(previewUrlMap));
//                }
//                resultList.add(object);
//            });
//        }
//        return resultList;
        return emergencyPlanList;
    }

    /**
     * 查询匹配列表
     */
    @Override
    public PageData<List<CommEmergencyPlan>> match(Integer current, Integer size, String planType, String planLevel,
                                                   Integer planPeople, BigDecimal planFireArea) {
        List<CommEmergencyPlan> emergencyPlanList = baseMapper.selectByConditionNoPage(null, null, null, null, null);
        Map<Long, CommEmergencyPlan> id2Entity = emergencyPlanList.stream().collect(
                Collectors.toMap(CommEmergencyPlan::getId, Function.identity(), (key1, key2) -> key2));

        //统计id出现的次数
        Map<Long, Integer> id2Count = new HashMap<>();
        emergencyPlanList.forEach(commEmergencyPlan -> {id2Count.put(commEmergencyPlan.getId(), 0);});

        List<CommEmergencyPlan> planTypeList = new ArrayList<>();
        if (StrUtil.isNotEmpty(planType)) {
            planTypeList = emergencyPlanList.stream().filter(
                    commEmergencyPlan -> planType.equals(commEmergencyPlan.getPlanType())).collect(Collectors.toList());
        }
        planTypeList.forEach(commEmergencyPlan -> {
            Integer count = id2Count.get(commEmergencyPlan.getId());
            id2Count.put(commEmergencyPlan.getId(), ++count);
        });

        List<CommEmergencyPlan> planLevelList = new ArrayList<>();
        if (StrUtil.isNotEmpty(planLevel)) {
            planLevelList = emergencyPlanList.stream().filter(
                    commEmergencyPlan -> planLevel.equals(commEmergencyPlan.getPlanLevel())).collect(
                    Collectors.toList());
        }
        planLevelList.forEach(commEmergencyPlan -> {
            Integer count = id2Count.get(commEmergencyPlan.getId());
            id2Count.put(commEmergencyPlan.getId(), ++count);
        });

        List<CommEmergencyPlan> planPeopleList = new ArrayList<>();
        if (planPeople != null) {
            planPeopleList = emergencyPlanList.stream().filter(
                    commEmergencyPlan -> planPeople >= commEmergencyPlan.getPlanPeopleStart()
                            && planPeople <= commEmergencyPlan.getPlanPeopleEnd()).collect(Collectors.toList());
        }
        planPeopleList.forEach(commEmergencyPlan -> {
            Integer count = id2Count.get(commEmergencyPlan.getId());
            id2Count.put(commEmergencyPlan.getId(), ++count);
        });

        List<CommEmergencyPlan> planFireAreaList = new ArrayList<>();
        if (planFireArea != null) {
            planFireAreaList = emergencyPlanList.stream().filter(
                    commEmergencyPlan ->
                            planFireArea.compareTo(commEmergencyPlan.getPlanFireAreaStart()) >= 0
                                    && planFireArea.compareTo(commEmergencyPlan.getPlanFireAreaEnd()) <= 0).collect(
                    Collectors.toList());
        }
        planFireAreaList.forEach(commEmergencyPlan -> {
            Integer count = id2Count.get(commEmergencyPlan.getId());
            id2Count.put(commEmergencyPlan.getId(), ++count);
        });

        //等级
        int level = 4;
        //按照次数依次添加进集合
        List<CommEmergencyPlan> emergencyPlans = new ArrayList<>();
        for (int i = level; i >= 0; i--) {
            int finalI = i;
            id2Count.keySet().forEach(id -> {
                if (id2Count.get(id) == finalI) {
                    CommEmergencyPlan commEmergencyPlan = id2Entity.get(id);
                    commEmergencyPlan.setRatio(BigDecimal.valueOf(finalI).divide(
                            BigDecimal.valueOf(level)).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(
                            BigDecimal.valueOf(100)));
                    emergencyPlans.add(commEmergencyPlan);
                }
            });
        }

        List<CommEmergencyPlan> list = emergencyPlans.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(
                        Comparator.comparing(CommEmergencyPlan::getId)
                )), ArrayList::new));
        //排序
        list = list.stream().sorted(
                Comparator.comparing(CommEmergencyPlan::getRatio).reversed().thenComparing(
                        Comparator.comparing(CommEmergencyPlan::getId).reversed())).collect(
                Collectors.toList());
        int count = list.size();//分页总条数
        int pageTotals = (count / size) + ((count % size > 0) ? 1 : 0);//总页数计算
        List<CommEmergencyPlan> contentList = new ArrayList<>();//分页内容
        if (current <= pageTotals) {
            int fromIndex = (current - 1) * size;
            int toIndex = ((current == pageTotals) ? count : (current * size));
            contentList = list.subList(fromIndex, toIndex);
        }
        return PageData.<List<CommEmergencyPlan>>builder()
                .count(count)
                .current(current)
                .size(size)
                .datas(contentList)
                .build();
    }

}
